

#include "Bone.h"
#include <d3dx9math.h>

_BoneNode::_BoneNode()	: m_uID(0)
{
}
_BoneNode::~_BoneNode()
{
}	

uint32 _BoneNode::GetTotalChildCount()
{
	uint32 uCount = m_Children.GetCount();
	_BoneNode* pNode = NULL;
	GPOS pos = m_Children;
	while (pos)
	{
		pNode = m_Children.GetNext(pos);
		uCount += pNode->GetTotalChildCount();
	}

	return uCount;
}

void _BoneNode::TotalMatInv2Array(D3DXMATRIX* pArray)
{
	pArray[m_uID] = m_matInverse;
	_BoneNode* pNode = NULL;
	GPOS pos = m_Children;
	while (pos)
	{
		pNode = m_Children.GetNext(pos);
		pNode->TotalMatInv2Array(pArray);
	}
}

_BoneNode* _BoneNode::GetBoneNode(const char* szName)
{
	_BoneNode* pNode = NULL;
	if (m_strName == szName)
	{
		return this;
	}

	_BoneNode* pChild = NULL;
	GPOS pos = m_Children;
	while (pos)
	{
		pChild = m_Children.GetNext(pos);
		pNode = pChild->GetBoneNode(szName);
		if (pNode)
		{
			return pNode;
		}
	}

	return NULL;
}

_BoneNode* _BoneNode::GetBoneNode(const uint32& uID)
{
	_BoneNode* pNode = NULL;
	if ( m_uID == uID)
	{
		return this;
	}

	_BoneNode* pChild = NULL;
	GPOS pos = m_Children;
	while (pos)
	{
		pChild = m_Children.GetNext(pos);
		pNode = pChild->GetBoneNode(uID);
		if (pNode)
		{
			return pNode;
		}
	}

	return NULL;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////
void _Bone::Init()
{
	uint32 uBoneCount = GetBoneCount();

	D3DXMATRIX *mat = new D3DXMATRIX[uBoneCount];
	D3DXCreateBuffer(uBoneCount*sizeof(D3DXMATRIX),&m_pBoneOffsetBuf);

	m_RootBoneNode.TotalMatInv2Array(mat);
	memcpy(m_pBoneOffsetBuf->GetBufferPointer(),mat,uBoneCount*sizeof(D3DXMATRIX));

	m_pBoneInverseMat = reinterpret_cast<D3DXMATRIX*> (m_pBoneOffsetBuf->GetBufferPointer());
	delete [] mat;

}

const _BoneNode* _Bone::GetBoneNode(const char* szName)
{
	return m_RootBoneNode.GetBoneNode(szName);
}
const _BoneNode* _Bone::GetBoneNode(const uint32& uID)
{
	return m_RootBoneNode.GetBoneNode(uID);
}

const _ModelSocket* _Bone::GetSocketNode(const char* szName)
{
	_ModelSocket* pNode = NULL;
	VecModelSocket::iterator pos = m_vecSocket.begin();
	VecModelSocket::iterator end = m_vecSocket.end();
	for (;pos!=end;++pos)
	{
		pNode = &(*pos);
		if (pNode->m_strName == szName)
		{
			return pNode;
		}
	}
	return NULL;
}
const _ModelSocket* _Bone::GetSocketNode(const uint32& uID)
{
	_ModelSocket* pNode = NULL;
	VecModelSocket::iterator pos = m_vecSocket.begin();
	VecModelSocket::iterator end = m_vecSocket.end();
	for (;pos!=end;++pos)
	{
		pNode = &(*pos);
		if (pNode->m_uID == uID)
		{
			return pNode;
		}
	}
	return NULL;
}